package org.rufolfheszele.andpixelbyandpixel;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;

// TODO: Port Configuration
// TODO: Port WxUtils
// TODO: Xml parsing using Java: http://www.java-samples.com/showtutorial.php?tutorialid=152
// TODO: File handling on Android: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal

public class MainImageView extends View implements OnGestureListener, OnDoubleTapListener
{
	public MainImageView(Context context)
	{
		super(context);
		mGestureDetector = new GestureDetector(context, this);
		mGestureDetector.setOnDoubleTapListener(this);
		this.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
		mGameController = new MainGameController(this);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent motionEvent)
	{
		return mGestureDetector.onTouchEvent(motionEvent);
	}
	
	@Override
    protected void onDraw(Canvas canvas)
	{
		// TODO: Implement this as it is implemented in PixelByPixel
		super.onDraw(canvas);
		BitmapDrawable drawable = new BitmapDrawable(mGameController.getBitmap());
		
		drawable.setBounds(new Rect(0, 0, mGameController.getBitmap().getWidth() * mZooming, mGameController.getBitmap().getHeight() * mZooming));
		drawable.draw(canvas);
	}
	
	@Override
	public boolean onDown(MotionEvent motionEvent)
	{
		mIsUserMoving = mGameController.handleTouchDown(new Point((int)motionEvent.getX(), (int)motionEvent.getY()));
		
		// Consume the event
		return true;
	}

	@Override
	public boolean onFling(MotionEvent downMotionEvent, MotionEvent upMotionEvent, float velocityX, float velocityY)
	{
		if(true == mIsUserMoving)
			mGameController.handleTouchUp(new Point((int)upMotionEvent.getX(), (int)upMotionEvent.getY()));
		
		// Consume the event
		return true;
	}

	@Override
	public void onLongPress(MotionEvent arg0)
	{
		// Nothing to do yet
	}

	@Override
	public boolean onScroll(MotionEvent downMotionEvent, MotionEvent moveMotionEvent, float distanceX, float distanceY)
	{
		if(true == mIsUserMoving)
			mGameController.handleTouchMove(new Point((int)moveMotionEvent.getX(), (int)moveMotionEvent.getY()));
		else
		{
			// Calculate the scrolling limits if needed - at creation and zooming in or out
			if(-1 == mMaxScrollX)
			{
				if(this.getWidth() < mGameController.getBitmap().getWidth() * mZooming)
					mMaxScrollX = (mGameController.getBitmap().getWidth() * mZooming) - this.getWidth();
				else
					mMaxScrollX = 0;
			}
			if(-1 == mMaxScrollY)
			{
				if(this.getHeight() < mGameController.getBitmap().getHeight() * mZooming)
					mMaxScrollY = (mGameController.getBitmap().getHeight() * mZooming) - this.getHeight();
				else
					mMaxScrollY = 0;
			}
			// Calculate the allowed distances
			if(this.getScrollX() + distanceX > mMaxScrollX)
				distanceX = mMaxScrollX - this.getScrollX();
			if(this.getScrollX() + distanceX < 0)
				distanceX = -this.getScrollX();
			if(this.getScrollY() + distanceY > mMaxScrollY)
				distanceY = mMaxScrollY - this.getScrollY();
			if(this.getScrollY() + distanceY < 0)
				distanceY = -this.getScrollY();
			this.scrollBy((int)distanceX, (int)distanceY);
		}

		// Consume the event
		return true;
	}

	@Override
	public void onShowPress(MotionEvent motionEvent)
	{
		// Nothing to do yet
	}

	@Override
	public boolean onSingleTapUp(MotionEvent motionEvent)
	{
		// Nothing to do, just consume the event
		return true;
	}
	
	@Override
	public boolean onDoubleTap(MotionEvent motionEvent)
	{
		if(1 == mZooming)
			mZooming = 2;
		else
			mZooming = 1;
		// Force to recalculate scrolling limits
		mMaxScrollX = -1;
		mMaxScrollY = -1;
		// Recalculate scrolling
		// No need to pass valid MotionEvent object, since they are not used in this case for sure
		// mIsUserMoving must be false
		this.onScroll(null, null, 0, 0);
		this.invalidate();
		
		return true;
	}

	@Override
	public boolean onDoubleTapEvent(MotionEvent motionEvent)
	{
		// Nothing to do, just consume the event
		return true;
	}

	@Override
	public boolean onSingleTapConfirmed(MotionEvent motionEvent)
	{
		// Nothing to do, just consume the event
		return true;
	}
	
	public IGameController getGameController()
	{
		return mGameController;
	}
	
	private GestureDetector	mGestureDetector	= null;
	private int				mZooming			= 1;
	private int				mMaxScrollX			= -1;
	private int				mMaxScrollY			= -1;
	private IGameController mGameController     = null;
	private boolean			mIsUserMoving		= false;
}
